using System.Collections.Generic;
using System.Linq;
using AtomicCms.Common.IDataContext;
using AtomicCms.Common.Models;

namespace AtomicCms.Data.EntityFramework
{
    public class AtomicCmsDataRepository : IAtomicCmsDataRepository
    {
        private readonly IAtomicCmsDataContext _context;

        public AtomicCmsDataRepository(IAtomicCmsDataContext context)
        {
            _context = context;// new AtomicCmsEntities();
        }

        #region IAtomicCmsDataContext Members

        public ICollection<PageTag> GetPagesTags()
        {
            var r = from acPageTag in _context.ac_PageTags
                    select
                        new
                            {
                                acPageTag.PageId,
                                acPageTag.TagId
                            };

            var pageTags = new List<PageTag>(r.Count());
            foreach (var pageIdTagId in r)
            {
                pageTags.Add(new PageTag
                                 {
                                     Page = GetPage(pageTags, pageIdTagId.PageId),
                                     Tag = GetTag(pageTags, pageIdTagId.TagId)
                                 });
            }

            return pageTags;
        }

        #endregion

        private Page GetPage(IEnumerable<PageTag> pageTags, int pageId)
        {
            PageTag fromCache = pageTags.FirstOrDefault(x => x.Page.Id == pageId);
            if (null != fromCache)
            {
                return fromCache.Page;
            }

            return _context.ac_Pages.FirstOrDefault(x => x.Id == pageId).CreatePage();
        }

        private Tag GetTag(IEnumerable<PageTag> pageTags, int tagId)
        {
            PageTag fromCache = pageTags.FirstOrDefault(x => x.Tag.Id == tagId);

            if (fromCache != null)
            {
                return fromCache.Tag;
            }

            return _context.ac_Tags.FirstOrDefault(x => x.TagId == tagId).CreateTag();
        }

        public ICollection<Page> GetPagesWithTag(string tag)
        {
            var v = from p in _context.ac_Pages
                    join pt in _context.ac_PageTags on p.Id equals pt.PageId
                    join t in _context.ac_Tags on pt.TagId equals t.TagId
                    where t.TagName== tag
                    select p;
            List<Page> pages = new List<Page>(v.Count());
            foreach (ac_Pages p in v)
            {
                pages.Add(p.CreatePage());
            }

            return pages;
        }
    }
}